home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1992 Aladdin Enterprises. All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- This file is part of Ghostscript.
-
- Ghostscript is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
- to anyone for the consequences of using it or for whether it serves any
- particular purpose or works at all, unless he says so in writing. Refer
- to the Ghostscript General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute
- Ghostscript, but only under the conditions described in the Ghostscript
- General Public License. A copy of this license is supposed to have been
- given to you along with Ghostscript so you can know your rights and
- responsibilities. It should be in a file named COPYING. Among other
- things, the copyright notice and this notice must be preserved on all
- copies. */
-
- /* gdevgimg.c */
- /* GEM image file format devices for Ghostscript */
- #include "gdevprn.h"
- #include "gserrors.h" /* REALLY? */
-
- /* This driver supports the GEM image format mainly used on Atari ST computers.
- * I coded this driver by changing the PCX drivers originally written by
- * Phil Conrad. It supports only monochrome picture because of the
- * difficulties with storing the color palette in the GEM image format. For
- * comments and bug reports please contact:
- * haebler@dmswwu1a.uni-muenster.de
- * Marcus Haebler, 10.08.92 */
-
- /* ------ The device descriptors ------ */
-
- /*
- * Standard U.S. page width and height. A4 paper is 8.4" x 11.7".
- */
- #define WIDTH_10THS 85
- #define HEIGHT_10THS 110
-
- /*
- * Default X and Y resolution.
- */
- #define X_DPI 72
- #define Y_DPI 72
-
- /* Monochrome. */
-
- private dev_proc_print_page (gemimg_print_page);
-
- gx_device_printer gs_gemimg_device =
- prn_device (prn_std_procs, "gemimg",
- WIDTH_10THS, HEIGHT_10THS,
- X_DPI, Y_DPI,
- 0, 0, 0, 0, /* margins */
- 1, gemimg_print_page);
-
- /* ------ Private definitions ------ */
-
- typedef struct
- {
- short im_version; /* normally '1' */
- short im_headlength; /* length in words */
- short im_nplanes; /* number of color planes */
- short im_patlen; /* pattern length in bytes (usually 2) */
- short im_pixwidth; /* pixel width in mm/1000 */
- short im_pixheight; /* pixel height in mm/1000 */
- short im_scanwidth; /* line width in pixels */
- short im_nlines; /* number of lines */
- } img_header;
-
-
- /* Write a monochrome GEM image page. */
- private int
- gemimg_print_page (gx_device_printer * pdev, FILE * file)
- {
- img_header header;
- int height = pdev->height;
- uint raster = (pdev->width + 7) >> 3; /* how many bytes per line */
- char *row1 = (char *) gs_malloc (raster, 1, "img line buffer 1");
- char *row2 = (char *) gs_malloc (raster, 1, "img line buffer 2");
- int y = 0, n, m, z, x = 0;
- int code = 0; /* return code */
-
- /* setup the header struct */
- header.im_version = 1;
- header.im_headlength = 8;
- header.im_nplanes = 1;
- header.im_patlen = 2;
- header.im_pixwidth = (short) (25400. / pdev->x_pixels_per_inch + 0.5);
- header.im_pixheight = (short) (25400. / pdev->y_pixels_per_inch + 0.5);
- header.im_scanwidth = pdev->width;
- header.im_nlines = pdev->height;
-
- if (row1 == 0 || row2 == 0) /* can't allocate row buffer*/
- return gs_error_VMerror;
-
- /* Write the header. */
-
- fwrite ((const char *) &header, 1, 16, file);
-
- /* Dump the contents of the image. */
- while (y < height)
- {
- gdev_prn_copy_scan_lines (pdev, y, row1, raster);
- for (n = 1; ((n + y) < height && n < 255); n++) /* repeating lines? */
- {
- gdev_prn_copy_scan_lines (pdev, y + n, row2, raster);
- if (memcmp ((char *) row1, (char *) row2, raster) != 0)
- {
- break;
- }
- }
- if (n > 1)
- {
- fwrite ("\x00\x00\xff", 3, 1, file);
- fputc (n, file);
- }
- /* code one line */
- while (x < raster)
- {
- if (row1[x] == '\x00')/* solid run with \0 ? */
- {
- for (m = 1; (row1[x + m] == '\x00' && m < 127 &&
- (x + m) < raster); m++);
- fputc (m, file);
- x += m;
- continue;
- }
- if (row1[x] == '\xff')/* solid run with \xff ? */
- {
- for (m = 1; (row1[x + m] == '\xff' && m < 127 &&
- (x + m) < raster); m++);
- fputc (128 + m, file);
- x += m;
- continue;
- }
- /* Pattern run ? */
- if ((x + 3) < raster && row1[x] == row1[(x + 2)] &&
- row1[(x + 1)] == row1[(x + 3)])
- {
- for (m = 4; ((x + m + 1) < raster && row1[x]
- == row1[x + m] && row1[x + 1]
- == row1[x + m + 1] && m < 510); m += 2);
- fputc (0, file);
- fprintf (file, "%c%c%c", m / 2, row1[x], row1[x + 1]);
- x += m;
- continue;
- }
- /* It is a bit string */
- fputc (0x80, file);
- for (m = 1; (x + m) < raster && row1[x + m] != '\x00' &&
- row1[x + m] != '\xff' && m < 255; m++)
- {
- if (x + m + 3 < raster)
- {
- if (row1[x + m] == row1[x + m + 2] &&
- row1[x + m + 1] == row1[x + m + 3])
- break;
- }
- }
- fputc (m, file);
- for (z = 0; z < m; z++)
- fputc (row1[x + z], file);
- x += m;
- }
- y += n;
- x = 0;
- }
- gs_free ((char *) row1, raster, 1, "img line buffer 1");
- gs_free ((char *) row2, raster, 1, "img line buffer 2");
- return code;
- }
-